package org.softmed.action.states.custom;

import org.softmed.action.ActionStep;
import org.softmed.action.exception.StopException;
import org.softmed.action.interfaces.SafeHaven;
import org.softmed.action.interfaces.SelfExceptionSolver;
import org.softmed.action.interfaces.StopExecution;
import org.softmed.action.states.State;

public class ExecutingState extends State {

	protected boolean executionStopped;
	protected ActionStep currentExecuter;
	protected ActionStep safeHaven;

	public ExecutingState(String name) {
		super(name);
	}

	@Override
	public void execute() throws Throwable {
		if (stateChangeListener != null)
			stateChangeListener.stateChanged(this);

		executionStopped = false;

		int i = 0;

		ActionStep executer = null;

		if (currentExecuter != null) {
			i = actionSteps.indexOf(currentExecuter);
			i++;
		}

		while (i < actionSteps.size()) {
			executer = actionSteps.get(i);
			currentExecuter = executer;

			if (executer instanceof SafeHaven)
				safeHaven = executer;

			try {

				executer.execute();

			} catch (Throwable t) {
				failedAction = executer;
				exception = t;

//				if (t instanceof StopException)
//					throw t;
				// t.printStackTrace();

				if (safeHaven != null)
					currentExecuter = safeHaven;

				if (executer instanceof SelfExceptionSolver)
					((SelfExceptionSolver) executer).resolveMyOwnException(t);

				if (safeHaven != null) {
					eventMap.runEvent("recover");
				} else {
					goFailure();
				}

				throw t;
			}

			if (executer instanceof StopExecution)
				executionStopped = ((StopExecution) executer)
						.isExecutionStopped();

			if (executionStopped)
				return;

			++i;
		}

		goSuccess();

	}

	public boolean isExecutionStopped() {
		return executionStopped;
	}

	public ActionStep getCurrentExecuter() {
		return currentExecuter;
	}

	public ActionStep getSafeHaven() {
		return safeHaven;
	}

}
